#include "shell.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "elog.h"

/*********************************************************************
 * CONSTANTS
 *********************************************************************/
#define assert_test(expr) ((expr) ? (elog_raw("%-32s ok.\r\n",__func__)): (elog_raw("%-32s error.\r\n",__func__)))

/*********************************************************************
 * EXTERN FUNCTIONS
 *********************************************************************/

/*********************************************************************
 * FUNCTIONS
 *********************************************************************/

void  test_shell_verify_dec_u8(void)
{
  const char datas[] = "257";
  uint8_t rsp = verify_dec_u8(datas);
  assert_test(rsp==SHELL_OK);
}

void  test_shell_verify_dec_u16(void)
{
  const char datas[] = "65535";
  const char datas2[] = "65536";
  uint8_t rsp = verify_dec_u16(datas);
  assert_test(rsp==SHELL_OK);
  rsp = verify_dec_u16(datas2);
  assert_test(rsp==SHELL_ERR);
}

void test_shell_verify_dec_flt(void)
{
  const char datas[] = "3.1415";
  uint8_t rsp = verify_dec_flt(datas);
  assert_test(rsp==SHELL_OK);
}

void  test_shell_verify_hex_u8s(void)
{
  const char datas[] = "0xf";
  const char datas2[] = "0xff";
  const char datas3[] = "0xfff";
  uint8_t rsp = verify_hex_u8s(datas);
  assert_test(rsp==SHELL_ERR);
  rsp = verify_hex_u8s(datas2);
  assert_test(rsp==SHELL_OK);
  rsp = verify_hex_u8s(datas3);
  assert_test(rsp==SHELL_ERR);
}

void  test_shell_verify_hex_16b(void)
{
  const char datas[] = "0xfff";
  const char datas2[] = "0xffff";
  const char datas3[] = "0xfffff";
  uint8_t rsp = verify_hex_16b(datas);
  assert_test(rsp==SHELL_ERR);
  rsp = verify_hex_16b(datas2);
  assert_test(rsp==SHELL_OK);
  rsp = verify_hex_16b(datas3);
  assert_test(rsp==SHELL_ERR);
}

void  test_shell_verify_hex_32b(void)
{
  const char datas[] = "0xfffffff";
  const char datas2[] = "0xffffffff";
  const char datas3[] = "0xfffffffff";
  uint8_t rsp = verify_hex_32b(datas);
  assert_test(rsp==SHELL_ERR);
  rsp = verify_hex_32b(datas2);
  assert_test(rsp==SHELL_OK);
  rsp = verify_hex_32b(datas3);
  assert_test(rsp==SHELL_ERR);
}

void  test_shell_convert_hex_to_u8(void)
{
  const char datas[] = "f";
  const char datas2[] = "0xff";
  uint8_t rsp = convert_hex_to_u8(datas);
  assert_test(rsp==15);
  rsp = convert_hex_to_u8(datas2);
  assert_test(rsp==255);
}

void  test_shell_convert_hex_to_u16(void)
{
  const char datas[] = "0xfff";
  const char datas2[] = "ffff";
  uint32_t rsp = convert_hex_to_u16(datas);
  assert_test(rsp==4095);
  rsp = convert_hex_to_u16(datas2);
  assert_test(rsp==65535);
}

void  test_shell_convert_hex_to_u32(void)
{
  const char datas[] = "fffffff";
  const char datas2[] = "ffffffff";
  uint32_t rsp = convert_hex_to_u32(datas);
  assert_test(rsp==0xfffffff);
  rsp = convert_hex_to_u32(datas2);
  assert_test(rsp==0xffffffff);
}

void  test_shell_parse_text(void)
{
  uint8_t rsp;
  char datas[64];
  // uint8_t datas[] = "IP 192.168.1.20 24 192.168.1.1\r\n";
  strcpy( datas, "NB hello \"hello\"\r\n" );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  strcpy( datas, "NB hello \"hello\" 5\r\n" ); // 多参数
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  strcpy( datas, "NB hello \"hello\r\n" ); // 异常结尾
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  strcpy( datas, "NB \"hello 5\" \"hello 5\r\n" ); // 异常结尾 + 多参数
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  strcpy( datas, "NB \"hello\\n\" \"hello\\n\"\r\n" ); // 带格式转换符
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  strcpy( datas, "NB \"hello\\n\" \"hello\\n\" 5\r\n" ); // 带格式转换符 + 多参数
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  strcpy( datas, "NB \"hello\\n\" \"hello\\n\r\n" ); // 带格式转换符+异常结尾
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  strcpy( datas, "NB \"hello\\n 5\" \"hello\\n 5\r\n" ); // 带格式转换符+异常结尾 + 多参数
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
}

void  test_shell_md(void)
{
  uint8_t rsp,adr[6]="hello";
  uint8_t u8v = 129;
  int8_t  i8v = -1;
  uint16_t u16v = 65535;
  int16_t  i16v = -2;
  uint32_t u32v = 65537;
  int32_t  i32v = -3;
  float    flt = 3.14;
  char datas[128];

  snprintf( datas, 128, "MD 0x%08XI1 0x%08XU1 0x%08XI2 0x%08XU2 0x%08XI4 0x%08XU4 0x%08XG4\r\n",
                  (uint32_t)(&i8v),(uint32_t)(&u8v),(uint32_t)(&i16v),(uint32_t)(&u16v),(uint32_t)(&i32v),(uint32_t)(&u32v),(uint32_t)(&flt) );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  snprintf( datas, 128, "MD \r\n" );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
}

void  test_shell_mm(void)
{
  uint8_t rsp,adr[6]="hello";
  char datas[64];
  sprintf( datas, "INT 0x%08X 1\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "INT 0x%08X 1 -1\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "INT 0x%08X 2\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "INT 0x%08X 2 -1\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "INT 0x%08X 4\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "INT 0x%08X 4 -1\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "UINT 0x%08X 1\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "UINT 0x%08X 1 255 \r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "UINT 0x%08X 2\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "UINT 0x%08X 2 65535 \r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "UINT 0x%08X 4\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "UINT 0x%08X 4 65537 \r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "HEX 0x%08X 5\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "HEX 0x%08X 5 0x0001020304\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  strcpy((char*)adr,"01234");
  sprintf( datas, "STR 0x%08X 6\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "STR 0x%08X 5 \"world\"\r\n",(uint32_t)adr );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
}


int test(float a, int b, const char *p)
{
  elog_i("shell_test","a:%f b:%d p:%s",a,b,p);
  return 1;
}

void  test_shell_call(void)
{
  uint8_t rsp;
  char datas[64];
  sprintf( datas, "CALLD 0x%08X 3.14 0x00000001 \"hello world\"\r\n",(uint32_t)test );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
}

void  test_shell_parse_login(void)
{
  uint8_t rsp;
  char datas[64];
  strcpy( datas, "HELP\r\n" );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "LOGIN %s\r\n", SHELL_LOGIN_KEY );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  strcpy( datas, "HELP\r\n" );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
  
  strcpy( datas, "LOGIN\r\n" );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  strcpy( datas, "HELP\r\n" );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();

  sprintf( datas, "LOGIN %s\r\n", SHELL_LOGIN_KEY );
  rsp = shell_put_buf(datas, (uint8_t)strlen((const char*)datas));
  shell_parse();
}

void shell_test( void )
{
  test_shell_parse_login();

  // test_shell_verify_dec_u8();
  // test_shell_verify_dec_u16();
  // test_shell_verify_dec_flt();
  // test_shell_verify_hex_u8s();
  // test_shell_verify_hex_16b();
  // test_shell_verify_hex_32b();
  
  // test_shell_convert_hex_to_u8();
  // test_shell_convert_hex_to_u16();
  // test_shell_convert_hex_to_u32();

  // test_shell_parse_text();

  // test_shell_mm();

  test_shell_md();

  test_shell_call();
}
